import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:lib_uikit/lib_uikit.dart';
import 'package:lib_uikit/widgets/gt_button_v3.dart';
import 'package:lib_uikit/widgets/gt_selector_v3.dart';
import 'package:lib_uikit/widgets/time_picker/gt_picker_show_selector_v3.dart';
import 'package:lib_uikit/widgets/time_picker/model/date_item_model.dart';
import 'package:lib_uikit/widgets/time_picker/model/date_mode.dart';
import 'package:lib_uikit/widgets/time_picker/model/date_time_data.dart';
import 'package:lib_uikit/widgets/time_picker/model/date_type.dart';
import 'package:lib_uikit/widgets/time_picker/model/pduration.dart';
import 'package:lib_uikit/widgets/time_picker/model/suffix.dart';
import 'package:lib_uikit/widgets/time_picker/picker_style_v3.dart';
import 'package:lib_uikit/widgets/time_picker/route/date_picker_route.dart';
import '../time_utils.dart';

class DatePickerRouteAndSelector<T> extends PopupRoute<T> {
  DatePickerRouteAndSelector({
    this.mode,
    required this.initDate,
    this.pickerStyle,
    required this.maxDate,
    required this.minDate,
    this.startDate,
    this.endDate,
    this.suffix,
    this.onChanged,
    this.onConfirm,
    this.onDatesConfirm,
    this.onCancel,
    this.theme,
    this.barrierLabel,
    this.confirmText,
    this.cancelText,
    this.title,
    this.subTitle,
    this.startText,
    this.endText,
    this.startTextSelected,
    this.endTextSelected,
    this.showTopView,
    this.isDismissible,
    this.showSelector,
    this.list,
    this.calculateStartTimeWhenClick,
    this.selectorTitle,
    this.selectIndex,
    this.selectorBottomWidget,
    this.onCancelClick,
    RouteSettings? settings,
  }) : super(settings: settings);

  final DateMode? mode;
  late final PDuration initDate;
  late final PDuration maxDate;
  late final PDuration minDate;
  final PDuration? startDate;
  final PDuration? endDate;
  final Suffix? suffix;
  final ThemeData? theme;
  final DateCallback? onChanged;
  final DateCallback? onConfirm;
  final DatesCallback? onDatesConfirm;
  final Function(bool isCancel)? onCancel;
  final PickerStyle? pickerStyle;
  final String? confirmText;
  final String? cancelText;
  String? title;
  String? subTitle;
  String? startText;
  String? endText;
  bool? startTextSelected;
  bool? endTextSelected;
  final bool? showTopView;
  final bool? isDismissible;
  final bool? showSelector;
  final String? selectorTitle;
  final List<GTSelectorModalV3>? list;
  final PDuration Function(int index, PDuration endDate)? calculateStartTimeWhenClick;
  final int? selectIndex;
  final Widget? selectorBottomWidget;
  final VoidCallback? onCancelClick;

  @override
  Duration get transitionDuration => const Duration(milliseconds: 200);

  @override
  bool get barrierDismissible => isDismissible ?? true;

  @override
  bool didPop(T? result) {
    if (onCancel != null) {
      if (result == null) {
        onCancel!(false);
      } else if (!(result as bool)) {
        onCancel!(true);
      }
    }
    return super.didPop(result);
  }

  @override
  final String? barrierLabel;

  //蒙层背景色
  @override
  Color get barrierColor => Colors.black54;

  AnimationController? _animationController;

  @override
  AnimationController createAnimationController() {
    assert(_animationController == null);
    _animationController = BottomSheet.createAnimationController(navigator!.overlay!);
    return _animationController!;
  }

  @override
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
    Widget bottomSheet = MediaQuery.removePadding(
      context: context,
      removeTop: true,
      child: _PickerContentView(
        mode: mode,
        initData: initDate,
        maxDate: maxDate,
        minDate: minDate,
        pickerStyle: pickerStyle!,
        startDate: startDate,
        endDate: endDate,
        route: this,
      ),
    );
    if (theme != null) {
      bottomSheet = Theme(data: theme!, child: bottomSheet);
    }

    return bottomSheet;
  }
}

class _PickerContentView extends StatefulWidget {
  const _PickerContentView({
    Key? key,
    this.mode,
    required this.initData,
    required this.pickerStyle,
    required this.maxDate,
    required this.minDate,
    required this.route,
    required this.startDate,
    required this.endDate,
  }) : super(key: key);

  final DateMode? mode;
  final PDuration initData;
  final DatePickerRouteAndSelector route;
  final PickerStyle pickerStyle;

  // 限制时间
  final PDuration maxDate;
  final PDuration minDate;
  final PDuration? startDate;
  final PDuration? endDate;

  @override
  State<StatefulWidget> createState() => _PickerState(
      this.mode, this.initData, this.maxDate, this.minDate, this.pickerStyle, this.startDate, this.endDate);
}

class _PickerState extends State<_PickerContentView> {
  late final PickerStyle _pickerStyle;

  // 是否显示 [年月日时分秒]
  late DateItemModel _dateItemModel;

  // 初始 设置选中的数据
  PDuration _initSelectData;

  // 选中的数据  用于回传
  late PDuration _selectData;
  late PDuration _selectStartData;
  late PDuration _selectEndData;

  // 所有item 对应的数据
  late DateTimeData _dateTimeData;

  // 限制时间
  late final PDuration maxDate;
  PDuration minDate;
  Animation<double>? animation;
  Map<DateType, FixedExtentScrollController> scrollCtrl = {};

  // 选择器 高度  单独提出来，用来解决修改数据 不及时更新的BUG
  late double pickerItemHeight;
  String _startText = "";
  String _endText = "";
  String _caculatedStartText = "";
  bool _startTextSelected = false;
  bool _endTextSelected = false;
  bool isFirst = true;
  PDuration? _startDate;
  PDuration? _endDate;
  PDuration? _minDate;
  bool _needClearSelector = false;
  bool _isReset = false;
  int _selectIndex = -1;

  _PickerState(DateMode? mode, this._initSelectData, this.maxDate, this.minDate, this._pickerStyle, this._startDate,
      this._endDate) {
    _dateItemModel = DateItemModel.parse(mode!);
    pickerItemHeight = _pickerStyle.pickerItemHeight;
    _startDate = _startDate;
    _endDate = _endDate;
    _init();
  }

  _init() {
    scrollCtrl.clear();

    _dateTimeData = DateTimeData();
    int index = 0; // 初始选中值  Index
    _selectData = PDuration();

    /// minDate 和 maxDate 都初始化了，可以省略很多空判断，直接比较选中值 是否相等 _selectData.month == minDate.month
    /// -------年
    if (_dateItemModel.year) {
      index = 0;
      _dateTimeData.year = TimeUtils.calcYears(begin: minDate.year!, end: maxDate.year!);

      if (_initSelectData.year != null) {
        index = _dateTimeData.year.indexOf(_initSelectData.year);
        index = index < 0 ? 0 : index;
      }
      _selectData.year = _dateTimeData.year[index];
      scrollCtrl[DateType.Year] = FixedExtentScrollController(initialItem: index);
    }

    /// ------月
    // 选中的月 用于之后 day 的计算
    int selectMonth = 1;
    if (_dateItemModel.month) {
      index = 0;
      int begin = 1;
      int end = 12;
      // 限制区域
      if (intNotEmpty(minDate.month) && _selectData.year == minDate.year) {
        begin = minDate.month!;
      }
      if (intNotEmpty(maxDate.month) && _selectData.year == maxDate.year) {
        end = maxDate.month!;
      }

      _dateTimeData.month = TimeUtils.calcMonth(begin: begin, end: end);

      if (_initSelectData.month != null) {
        index = _dateTimeData.month.indexOf(_initSelectData.month);
        index = index < 0 ? 0 : index;
      }
      selectMonth = _dateTimeData.month[index];
      _selectData.month = selectMonth;
      scrollCtrl[DateType.Month] = FixedExtentScrollController(initialItem: index);
    }

    /// -------日   （有日肯定有 年月数据）
    if (_dateItemModel.day) {
      index = 0;
      int begin = 1;
      int end = 31;
      // 限制区域
      if (intNotEmpty(minDate.day) || intNotEmpty(maxDate.day)) {
        if (_selectData.year == minDate.year && _selectData.month == minDate.month) {
          begin = minDate.day!;
        }
        if (_selectData.year == maxDate.year && _selectData.month == maxDate.month) {
          end = maxDate.day!;
        }
      }

      _dateTimeData.day = TimeUtils.calcDay(_initSelectData.year!, selectMonth, begin: begin, end: end);

      if (_initSelectData.day != null) {
        index = _dateTimeData.day.indexOf(_initSelectData.day);
        index = index < 0 ? 0 : index;
      }
      _selectData.day = _dateTimeData.day[index];
      scrollCtrl[DateType.Day] = FixedExtentScrollController(initialItem: index);
    }

    /// ---------时
    if (_dateItemModel.hour) {
      index = 0;
      int begin = 0;
      int end = 23;
      // 限制区域
      if (intNotEmpty(minDate.hour)) {
        begin = minDate.hour!;
      }
      if (intNotEmpty(maxDate.hour)) {
        end = maxDate.hour!;
      }

      _dateTimeData.hour = TimeUtils.calcHour(begin: begin, end: end);

      if (_initSelectData.hour != null) {
        index = _dateTimeData.hour.indexOf(_initSelectData.hour);
        index = index < 0 ? 0 : index;
      }
      _selectData.hour = _dateTimeData.hour[index];
      scrollCtrl[DateType.Hour] = FixedExtentScrollController(initialItem: index);
    }

    /// ---------分
    if (_dateItemModel.minute) {
      index = 0;
      int begin = 0;
      int end = 59;
      // 限制区域
      if (intNotEmpty(minDate.minute) || intNotEmpty(maxDate.minute)) {
        if (_dateItemModel.hour) {
          // 如果有上级 还有时，要根据时再判断
          if (_selectData.hour == minDate.hour) {
            begin = minDate.minute!;
          }
          if (_selectData.hour == maxDate.hour) {
            end = maxDate.minute!;
          }
        } else {
          // 上级没有时间限制 直接取
          if (intNotEmpty(minDate.minute)) {
            begin = minDate.minute!;
          }
          if (intNotEmpty(maxDate.minute)) {
            end = maxDate.minute!;
          }
        }
      }

      _dateTimeData.minute = TimeUtils.calcMinAndSecond(begin: begin, end: end);

      if (_initSelectData.minute != null) {
        index = _dateTimeData.minute.indexOf(_initSelectData.minute);
        index = index < 0 ? 0 : index;
      }
      _selectData.minute = _dateTimeData.minute[index];
      scrollCtrl[DateType.Minute] = FixedExtentScrollController(initialItem: index);
    }

    /// --------秒
    if (_dateItemModel.second) {
      index = 0;
      int begin = 0;
      int end = 59;
      // 限制区域
      if (intNotEmpty(minDate.second) || intNotEmpty(maxDate.second)) {
        if (_dateItemModel.hour && _dateItemModel.minute) {
          // 如果有上级 还有时 分，要根据时分再判断
          if (_selectData.hour == minDate.hour && _selectData.minute == minDate.minute) {
            begin = minDate.second!;
          }
          if (_selectData.hour == maxDate.hour && _selectData.minute == maxDate.minute) {
            end = maxDate.second!;
          }
        } else if (_dateItemModel.minute) {
          /// 上级没有时，只有分限制
          if (_selectData.minute == minDate.minute) {
            begin = minDate.second!;
          }
          if (_selectData.minute == maxDate.minute) {
            end = maxDate.second!;
          }
        } else {
          /// 上级没有时间限制 直接取
          if (intNotEmpty(minDate.second)) {
            begin = minDate.second!;
          }
          if (intNotEmpty(maxDate.second)) {
            end = maxDate.second!;
          }
        }
      }

      _dateTimeData.second = TimeUtils.calcMinAndSecond(begin: begin, end: end);

      if (_initSelectData.second != null) {
        index = _dateTimeData.second.indexOf(_initSelectData.second);
        index = index < 0 ? 0 : index;
      }
      _selectData.second = _dateTimeData.second[index];
      scrollCtrl[DateType.Second] = FixedExtentScrollController(initialItem: index);
    }
  }

  @override
  void dispose() {
    scrollCtrl.forEach((key, value) {
      value.dispose();
    });
    super.dispose();
  }

  @override
  void initState() {
    _startText = widget.route.startText ?? "";
    _endText = widget.route.endText ?? "";
    _endTextSelected = widget.route.endTextSelected ?? false;
    _startTextSelected = widget.route.startTextSelected ?? !_endTextSelected;
    _minDate = widget.route.minDate;
    _selectIndex = widget.route.selectIndex ?? -1;
    if (_endTextSelected) {
      initClickEndTime();
    }
    //初始化弹窗的开始时间
    if (_selectIndex > -1) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        initSelectorStartDate(_selectIndex);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      child: AnimatedBuilder(
        animation: widget.route.animation!,
        builder: (BuildContext context, Widget? child) {
          return ClipRect(
            child: CustomSingleChildLayout(
              delegate: _BottomPickerLayout(widget.route.animation!.value, _pickerStyle),
              child: GestureDetector(
                child: Material(
                  color: Colors.transparent,
                  child: _renderPickerView(),
                ),
              ),
            ),
          );
        },
      ),
    );
  }

  void _setPicker(DateType dateType, int selectIndex) {
    // 得到新的选中的数据
    var selectValue = _dateTimeData.getListByName(dateType)[selectIndex];
    // 更新选中数据
    _selectData.setSingle(dateType, selectValue);

    switch (dateType) {
      case DateType.Year:
        _setYear();
        break;
      case DateType.Month:
        _setMonth();
        break;
      case DateType.Day:
        break;
      case DateType.Hour:
        _setHour();
        break;
      case DateType.Minute:
        _setMinute();
        break;
      case DateType.Second:
        break;
    }
    setState(() {
      if (isFirst) {
        _startText = '${_selectData.year}-'
            '${TimeUtils.intToStr(_selectData.month ?? 0)}-'
            '${TimeUtils.intToStr(_selectData.day ?? 0)}';
        setState(() {
          _needClearSelector = _caculatedStartText != _startText;
        });
      } else {
        _endText = '${_selectData.year}-'
            '${TimeUtils.intToStr(_selectData.month ?? 0)}-'
            '${TimeUtils.intToStr(_selectData.day ?? 0)}';
      }
    });
    _notifyLocationChanged();
  }

  // -------------------- set   begin ------------
  void _setYear() {
    // 可能造成 月 日 list的改变
    if (_dateItemModel.month) {
      // 月的数据是否需要更新
      bool updateMonth = false;
      bool updateDay = false;

      /// 如果只有月
      int beginMonth = 1;
      int endMonth = 12;
      // 限制区域
      if (intNotEmpty(minDate.month) && _selectData.year == minDate.year) {
        beginMonth = minDate.month!;
      }
      if (intNotEmpty(maxDate.month) && _selectData.year == maxDate.year) {
        endMonth = maxDate.month!;
      }

      var resultMonth = TimeUtils.calcMonth(begin: beginMonth, end: endMonth);

      int jumpToIndexMonth = 0;

      if (!listEquals(_dateTimeData.month, resultMonth)) {
        //可能 选中的月份 由于设置了新数据后没有了
        // 小于不用考虑 会进else
        if (_selectData.month! > resultMonth.last) {
          jumpToIndexMonth = resultMonth.length - 1;
        } else {
          jumpToIndexMonth = resultMonth.indexOf(_selectData.month);
        }
        jumpToIndexMonth = jumpToIndexMonth < 0 ? 0 : jumpToIndexMonth;
        _selectData.month = resultMonth[jumpToIndexMonth];
        updateMonth = true;
      }

      /// 还有 日
      int jumpToIndexDay = 0;
      // 新的day 数据
      var resultDay;
      if (_dateItemModel.day) {
        int beginDay = 1;
        int endDay = 31;
        // 限制区域
        if (intNotEmpty(minDate.day) || intNotEmpty(maxDate.day)) {
          if (_selectData.year == minDate.year && _selectData.month == minDate.month) {
            beginDay = minDate.day!;
          }
          if (_selectData.year == maxDate.year && _selectData.month == maxDate.month) {
            endDay = maxDate.day!;
          }
        }
        resultDay = TimeUtils.calcDay(_selectData.year!, _selectData.month!, begin: beginDay, end: endDay);

        if (!listEquals(_dateTimeData.day, resultDay)) {
          //可能 选中的年 月份 由于设置了新数据后没有了
          // 小于不用考虑 会进else
          if (_selectData.day! > resultDay.last) {
            jumpToIndexDay = resultDay.length - 1;
          } else {
            jumpToIndexDay = resultDay.indexOf(_selectData.day);
          }
          jumpToIndexDay = jumpToIndexDay < 0 ? 0 : jumpToIndexDay;
          _selectData.day = resultDay[jumpToIndexDay];
          updateDay = true;
        }
      }

      if (updateMonth || updateDay) {
        setState(() {
          if (updateMonth) {
            _dateTimeData.month = resultMonth;
            scrollCtrl[DateType.Month]?.jumpToItem(jumpToIndexMonth);
          }
          if (updateDay) {
            _dateTimeData.day = resultDay;
            scrollCtrl[DateType.Day]?.jumpToItem(jumpToIndexDay);
          }

          /// FIX:https://github.com/flutter/flutter/issues/22999
          pickerItemHeight = _pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000;
        });
      }
    }
  }

  void _setMonth() {
    // 可能造成 日 list的改变
    bool updateDay = false;
    int jumpToIndexDay = 0;
    // 新的day 数据
    var resultDay;
    if (_dateItemModel.day) {
      int beginDay = 1;
      int endDay = 31;
      // 限制区域
      if (intNotEmpty(minDate.day) || intNotEmpty(maxDate.day)) {
        if (_selectData.year == minDate.year && _selectData.month == minDate.month) {
          beginDay = minDate.day!;
        }
        if (_selectData.year == maxDate.year && _selectData.month == maxDate.month) {
          endDay = maxDate.day!;
        }
      }
      resultDay = TimeUtils.calcDay(_selectData.year!, _selectData.month!, begin: beginDay, end: endDay);

      if (!listEquals(_dateTimeData.day, resultDay)) {
        //可能 选中的年 月份 由于设置了新数据后没有了
        // 小于不用考虑 会进else
        if (_selectData.day! > resultDay.last) {
          jumpToIndexDay = resultDay.length - 1;
        } else {
          jumpToIndexDay = resultDay.indexOf(_selectData.day);
        }
        jumpToIndexDay = jumpToIndexDay < 0 ? 0 : jumpToIndexDay;
        _selectData.day = resultDay[jumpToIndexDay];
        updateDay = true;
      }
    }
    if (updateDay) {
      setState(() {
        _dateTimeData.day = resultDay;
        scrollCtrl[DateType.Day]?.jumpToItem(jumpToIndexDay);

        /// FIX:https://github.com/flutter/flutter/issues/22999
        pickerItemHeight = _pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000;
      });
    }
  }

  void _setHour() {
    // 可能造成 分 秒 list的改变
    if (_dateItemModel.minute) {
      // 月的数据是否需要更新
      bool updateMinute = false;
      bool updateSecond = false;

      /// 如果只有分
      int beginMinute = 0;
      int endMinute = 59;
      // 限制区域
      if (intNotEmpty(minDate.minute) && _selectData.hour == minDate.hour) {
        beginMinute = minDate.minute!;
      }
      if (intNotEmpty(maxDate.minute) && _selectData.hour == maxDate.hour) {
        endMinute = maxDate.minute!;
      }

      var resultMinute = TimeUtils.calcMinAndSecond(begin: beginMinute, end: endMinute);

      int jumpToIndexMinute = 0;

      if (!listEquals(_dateTimeData.month, resultMinute)) {
        //可能 选中的时间 由于设置了新数据后没有了
        // 小于不用考虑 会进else
        if (_selectData.minute! > resultMinute.last) {
          jumpToIndexMinute = resultMinute.length - 1;
        } else {
          jumpToIndexMinute = resultMinute.indexOf(_selectData.minute);
        }
        jumpToIndexMinute = jumpToIndexMinute < 0 ? 0 : jumpToIndexMinute;
        _selectData.minute = resultMinute[jumpToIndexMinute];
        updateMinute = true;
      }

      /// 还有 秒
      int jumpToIndexSecond = 0;
      // 新的day 数据
      var resultSecond;
      if (_dateItemModel.second) {
        int beginSecond = 0;
        int endSecond = 59;
        // 限制区域
        if (intNotEmpty(minDate.second) || intNotEmpty(maxDate.second)) {
          if (_selectData.hour == minDate.hour && _selectData.minute == minDate.minute) {
            beginSecond = minDate.second!;
          }
          if (_selectData.hour == maxDate.hour && _selectData.minute == maxDate.minute) {
            endSecond = maxDate.second!;
          }
        }
        resultSecond = TimeUtils.calcMinAndSecond(begin: beginSecond, end: endSecond);

        if (!listEquals(_dateTimeData.second, resultSecond)) {
          //可能 选中的时 分 由于设置了新数据后没有了
          // 小于不用考虑 会进else
          if (_selectData.second! > resultSecond.last) {
            jumpToIndexSecond = resultSecond.length - 1;
          } else {
            jumpToIndexSecond = resultSecond.indexOf(_selectData.second);
          }
          jumpToIndexSecond = jumpToIndexSecond < 0 ? 0 : jumpToIndexSecond;
          _selectData.second = resultSecond[jumpToIndexSecond];
          updateSecond = true;
        }
      }

      if (updateMinute || updateSecond) {
        setState(() {
          if (updateMinute) {
            _dateTimeData.minute = resultMinute;
            scrollCtrl[DateType.Minute]?.jumpToItem(jumpToIndexMinute);
          }
          if (updateSecond) {
            _dateTimeData.second = resultSecond;
            scrollCtrl[DateType.Second]?.jumpToItem(jumpToIndexSecond);
          }

          /// FIX:https://github.com/flutter/flutter/issues/22999
          pickerItemHeight = _pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000;
        });
      }
    }
  }

  void _setMinute() {
    // 可能造成 秒 list的改变
    bool updateSecond = false;
    int jumpToIndexSecond = 0;
    // 新的day 数据
    var resultSecond;
    if (_dateItemModel.second) {
      int beginSecond = 0;
      int endSecond = 59;
      // 限制区域
      if (intNotEmpty(minDate.second) || intNotEmpty(maxDate.second)) {
        if (_dateItemModel.hour) {
          // 如果上面还有 时
          if (_selectData.hour == minDate.hour && _selectData.minute == minDate.minute) {
            beginSecond = minDate.second!;
          }
          if (_selectData.hour == maxDate.hour && _selectData.minute == maxDate.minute) {
            endSecond = maxDate.second!;
          }
        } else {
          // 没有时，分秒
          if (_selectData.minute == minDate.minute) {
            beginSecond = minDate.second!;
          }
          if (_selectData.minute == maxDate.minute) {
            endSecond = maxDate.second!;
          }
        }
      }
      resultSecond = TimeUtils.calcMinAndSecond(begin: beginSecond, end: endSecond);

      if (!listEquals(_dateTimeData.second, resultSecond)) {
        //可能 选中的分 由于设置了新数据后没有了
        // 小于不用考虑 会进else
        if (_selectData.second! > resultSecond.last) {
          jumpToIndexSecond = resultSecond.length - 1;
        } else {
          jumpToIndexSecond = resultSecond.indexOf(_selectData.second);
        }
        jumpToIndexSecond = jumpToIndexSecond < 0 ? 0 : jumpToIndexSecond;
        _selectData.second = resultSecond[jumpToIndexSecond];
        updateSecond = true;
      }
    }
    if (updateSecond) {
      setState(() {
        _dateTimeData.second = resultSecond;
        scrollCtrl[DateType.Second]?.jumpToItem(jumpToIndexSecond);

        /// FIX:https://github.com/flutter/flutter/issues/22999
        pickerItemHeight = _pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000;
      });
    }
  }

  // -------------------- set   end ------------

  void _notifyLocationChanged() {
    if (widget.route.onChanged != null) {
      widget.route.onChanged!(_selectData);
    }
  }

  double _pickerFontSize(String text) {
    if (text == '') return 18.0;

    if (_dateItemModel.length == 6 && (text.length > 4 && text.length <= 6)) {
      return 16.0;
    }

    if (text.length <= 6) {
      return 16.0;
    } else if (text.length < 9) {
      return 14.0;
    } else if (text.length < 13) {
      return 12.0;
    } else {
      return 10.0;
    }
  }

  Widget _renderPickerView() {
    Widget itemView = _renderItemView();

    if (!_pickerStyle.showTitleBar && _pickerStyle.menu == null) {
      return itemView;
    }
    List<Widget> viewList = <Widget>[];
    if (widget.route.showTopView ?? true) {
      viewList.add(_titleView());
    }
    viewList.add(itemView);
    if (widget.route.selectorBottomWidget != null) {
      viewList.add(widget.route.selectorBottomWidget!);
    }
    viewList.add(_bottomView());
    viewList.add(Container(
      color: GTColorsV3.cmpt16.color,
      height: GTScreen.bottomSafeHeight,
    ));
    return Column(children: viewList);
  }

  Widget _renderItemView() {
    // 选择器
    List<Widget> pickerList = [];
    if (_dateItemModel.year) pickerList.add(pickerView(DateType.Year));
    if (_dateItemModel.month) pickerList.add(pickerView(DateType.Month));
    if (_dateItemModel.day) pickerList.add(pickerView(DateType.Day));
    if (_dateItemModel.hour) pickerList.add(pickerView(DateType.Hour));
    if (_dateItemModel.minute) pickerList.add(pickerView(DateType.Minute));
    if (_dateItemModel.second) pickerList.add(pickerView(DateType.Second));

    return Stack(
      clipBehavior: Clip.none,
      children: [
        Container(
          height: _pickerStyle.pickerHeight,
          decoration: BoxDecoration(
            color: _pickerStyle.backgroundColor,
            borderRadius: widget.route.showTopView ?? true
                ? const BorderRadius.vertical(top: Radius.circular(0))
                : const BorderRadius.vertical(top: Radius.circular(8)),
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: pickerList,
          ),
        ),
        Positioned(
          top: -1,
          left: 0,
          right: 0,
          child: Container(
            color: GTColorsV3.cmpt16.color,
            height: 2,
          ),
        ),
        Positioned(
          left: 0,
          right: 0,
          bottom: -1,
          child: Container(
            color: GTColorsV3.cmpt16.color,
            height: 2,
          ),
        ),
        Positioned(
          left: 12,
          right: 12,
          top: (_pickerStyle.pickerHeight - pickerItemHeight) / 2,
          child: Container(
            color: GTColorsV3.divider5.color,
            height: 1,
          ),
        ),
        Positioned(
          left: 12,
          right: 12,
          top: (_pickerStyle.pickerHeight - pickerItemHeight) / 2 + pickerItemHeight - 1,
          child: Container(
            color: GTColorsV3.divider5.color,
            height: 1,
          ),
        ),
      ],
    );
  }

  ///  CupertinoPicker.builder
  Widget pickerView(DateType dateType) {
    return Expanded(
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 2),
        child: CupertinoPicker.builder(
          /// key ：年月拼接 就不会重复了 fixme
          /// 最好别使用key 会生成新的widget
          /// 官方的bug : https://github.com/flutter/flutter/issues/22999
          /// 临时方法 通过修改height
          scrollController: scrollCtrl[dateType],
          itemExtent: pickerItemHeight,
          selectionOverlay: _pickerStyle.itemOverlay,
          onSelectedItemChanged: (int selectIndex) => _setPicker(dateType, selectIndex),
          childCount: _dateTimeData.getListByName(dateType).length,
          itemBuilder: (_, index) {
            String text = '${_dateTimeData.getListByName(dateType)[index]}${widget.route.suffix?.getSingle(dateType)}';
            return Align(
                alignment: Alignment.center,
                child: Text(TimeUtils.intToStr(int.parse(text)),
                    style: gtTextStyleW500(color: _pickerStyle.textColor, fontSize: _pickerFontSize(text)),
                    textAlign: TextAlign.start));
          },
        ),
      ),
    );
  }

  // 选择器上面的view
  Widget _titleView() {
    if (_isReset) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        setState(() {
          _startText = widget.route.startText ?? "";
          _endText = widget.route.endText ?? "";
          _endTextSelected = widget.route.endTextSelected ?? false;
          _startTextSelected = widget.route.startTextSelected ?? !_endTextSelected;
          if (_endTextSelected) {
            List<String> list = (widget.route.endText ?? "").split('-');
            _endDate = PDuration(year: int.parse(list[0]), month: int.parse(list[1]), day: int.parse(list[2]));
            initClickEndTime();
          }
          _startDate = widget.route.startDate;
          _selectStartData = _startDate ?? PDuration();
          //初始化弹窗的开始时间
          if (_selectIndex>-1) {
            WidgetsBinding.instance.addPostFrameCallback((_) {
              initSelectorStartDate(_selectIndex);
            });
          } else {
            _needClearSelector = true;
          }
        });
        _isReset = false;
      });
    }
    return Container(
      width: MediaQuery.of(context).size.width,
      padding: const EdgeInsets.symmetric(horizontal: 16),
      decoration: BoxDecoration(
          color: GTColorsV3.cmpt16.color,
          borderRadius: const BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12))),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Padding(
                padding: const EdgeInsets.only(top: 24),
                child: Text(
                  widget.route.title ?? "",
                  style: gtTextStyleW700(fontSize: 16, color: GTColorsV3.text1.color),
                ),
              ),
              GestureDetector(
                onTap: () {
                  Navigator.pop(context, false);
                },
                child: Padding(
                  padding: const EdgeInsets.only(top: 16),
                  child: Icon(
                    GTIconFont.e89b,
                    color: GTColorsV3.icon3.color,
                    size: 16,
                  ),
                ),
              )
            ],
          ),
          if ((widget.route.subTitle ?? "").isNotEmpty) ...[
            const SizedBox(
              height: 24,
            ),
            Text(
              widget.route.subTitle ?? "",
              style: gtTextStyleW400(fontSize: 12, color: GTColorsV3.text3.color),
            ),
          ],
          if (widget.route.showSelector ?? false) ...[
            const SizedBox(
              height: 24,
            ),
            GTPickerShowSelectorV3(
              list: widget.route.list ?? [],
              needClear: _needClearSelector,
              selectIndex: _selectIndex,
              selectorTitle: widget.route.selectorTitle,
              onSingleClick: (index) {
                setState(() {
                  _selectIndex=index;
                  _needClearSelector = false;
                  initSelectorStartDate(index);
                });
              },
            ),
            const SizedBox(
              height: 4,
            )
          ],
          if (_startText.isNotEmpty && _endText.isNotEmpty) ...[
            const SizedBox(
              height: 12,
            ),
            Row(
              children: [
                Expanded(
                  child: GestureDetector(
                    onTap: () {
                      setState(() {
                        handleClickStartTime();
                      });
                    },
                    child: Container(
                      height: 40,
                      decoration: BoxDecoration(
                        borderRadius: const BorderRadius.all(Radius.circular(6)),
                        border:
                            Border.all(color: _startTextSelected ? GTColorsV3.text9.color : GTColorsV3.divider5.color),
                      ),
                      child: Center(
                        child: Text(
                          _startText ?? "",
                          style: gtTextStyleW500(
                            fontSize: 14,
                            color: _startTextSelected ? GTColorsV3.text1.color : GTColorsV3.text3.color,
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
                const SizedBox(
                  width: 16,
                ),
                GTThemeProvider.instance.isRTL()
                    ? Transform.rotate(
                        angle: pi,
                        child: Icon(
                          GTIconFont.e92c,
                          size: 16,
                          color: GTColorsV3.icon1.color,
                        ),
                      )
                    : Icon(
                        GTIconFont.e92c,
                        size: 16,
                        color: GTColorsV3.icon1.color,
                      ),
                const SizedBox(
                  width: 16,
                ),
                Expanded(
                  child: GestureDetector(
                    onTap: () {
                      setState(() {
                        _endTextSelected = true;
                        handleClickEndTime();
                      });
                    },
                    child: Container(
                      height: 40,
                      decoration: BoxDecoration(
                        borderRadius: const BorderRadius.all(Radius.circular(6)),
                        border:
                            Border.all(color: _endTextSelected ? GTColorsV3.text9.color : GTColorsV3.divider5.color),
                      ),
                      child: Center(
                        child: Text(
                          _endText ?? "",
                          style: gtTextStyleW500(
                            fontSize: 14,
                            color: _endTextSelected ? GTColorsV3.text1.color : GTColorsV3.text3.color,
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ],
          const SizedBox(
            height: 16,
          ),
        ],
      ),
    );
  }

  Widget _bottomView() {
    return Container(
      color: GTColorsV3.cmpt16.color,
      padding: const EdgeInsets.all(16),
      child: Row(
        children: [
          Expanded(
            child: GTButtonV3(
              text: widget.route.cancelText ?? "",
              buttonType: GTButtonTypeV3.secondary,
              buttonSize: GTButtonSizeV3.medium,
              isFullWidth: true,
              onPressed: () {
                if (!(widget.route.showSelector ?? false)) {
                  Navigator.pop(context, false);
                } else {
                  setState(() {
                    if (_selectIndex>-1) {
                      _needClearSelector = false;
                      _selectIndex=widget.route.selectIndex??-1;
                    }
                    _isReset = true;
                  });
                }
                widget.route.onCancelClick?.call();
              },
            ),
          ),
          const SizedBox(
            width: 8,
          ),
          Expanded(
            child: GTButtonV3(
              text: widget.route.confirmText ?? "",
              buttonSize: GTButtonSizeV3.medium,
              isFullWidth: true,
              onPressed: () {
                if (widget.route.onDatesConfirm != null) {
                  setState(() {
                    if (isFirst) {
                      handleClickEndTime();
                    } else {
                      widget.route.onDatesConfirm!(_selectStartData, _selectData);
                      Navigator.pop(context, false);
                    }
                  });
                }
                if (widget.route.onConfirm != null) {
                  widget.route.onConfirm!(_selectData);
                  Navigator.pop(context, false);
                }
              },
            ),
          ),
        ],
      ),
    );
  }

  void handleClickStartTime() {
    _selectEndData = PDuration(year: _selectData.year, month: _selectData.month, day: _selectData.day);
    _startTextSelected = true;
    _endTextSelected = false;
    isFirst = true;
    if (!(widget.route.showSelector ?? false)) {
      _endText = '${_selectData.year}-'
          '${TimeUtils.intToStr(_selectData.month ?? 0)}-'
          '${TimeUtils.intToStr(_selectData.day ?? 0)}';
      if (_minDate != null) {
        minDate = _minDate!;
      }
    }
    //更新选择器数据
    _init();
    //数据更新后，重置选择器下标
    resetStartDatePicker();
  }

  void initClickEndTime() {
    _startTextSelected = false;
    _endTextSelected = true;
    if (!_isReset) {
      _selectStartData = PDuration(year: _selectData.year, month: _selectData.month, day: _selectData.day);
      _startText = '${_selectData.year}-'
          '${TimeUtils.intToStr(_selectData.month ?? 0)}-'
          '${TimeUtils.intToStr(_selectData.day ?? 0)}';
    }
    isFirst = false;
//数据更新后，重置选择器下标
    resetEndDatePicker();
  }

  void handleClickEndTime() {
    _selectStartData = PDuration(year: _selectData.year, month: _selectData.month, day: _selectData.day);
    _startTextSelected = false;
    _endTextSelected = true;
    _startText = '${_selectData.year}-'
        '${TimeUtils.intToStr(_selectData.month ?? 0)}-'
        '${TimeUtils.intToStr(_selectData.day ?? 0)}';
    isFirst = false;
    //限制结束时间的开始时间
    if (!(widget.route.showSelector ?? false)) {
      minDate = _selectStartData;
    }
    //更新选择器数据
    _init();
    //数据更新后，重置选择器下标
    resetEndDatePicker();
  }

  void resetStartDatePicker() {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      //选择年份大于结束年份，更新结束日期的展示内容
      if ((_selectData.year ?? 0) > (_startDate?.year ?? 0)) {
        _startDate = PDuration(year: _selectData.year, month: _startDate?.month, day: _startDate?.day);
      }
      //更新_selectData用于数据回调
      _selectData = _startDate ?? PDuration();

      int yIndex = (_startDate?.year ?? 0) - (minDate.year ?? 0);
      scrollCtrl[DateType.Year]?.jumpToItem(yIndex);
      int mIndex = 0;
      if (minDate.year == _startDate?.year) {
        //如果年份相同
        mIndex = (_startDate?.month ?? 0) - (minDate.month ?? 0);
      } else {
        mIndex = (_startDate?.month ?? 0) - 1;
      }
      scrollCtrl[DateType.Month]?.jumpToItem(mIndex);
      int dIndex = 0;
      if (minDate.year == _startDate?.year && minDate.month == _startDate?.month) {
        //如果年份相同,并且月份相同
        dIndex = (_startDate?.day ?? 0) - (minDate.day ?? 0);
      } else {
        dIndex = (_startDate?.day ?? 0) - 1;
      }
      scrollCtrl[DateType.Day]?.jumpToItem(dIndex);
    });
  }

  ///结束时间选择器和文案展示逻辑处理
  void resetEndDatePicker() {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      //选择年份大于结束年份，更新结束日期的展示内容
      if ((_selectData.year ?? 0) > (_endDate?.year ?? 0)) {
        _endDate = PDuration(year: _selectData.year, month: _endDate?.month, day: _endDate?.day);
      }
      int yIndex = (_endDate?.year ?? 0) - (minDate.year ?? 0);
      scrollCtrl[DateType.Year]?.jumpToItem(yIndex);
      int mIndex = 0;
      if (minDate.year == _endDate?.year) {
        //如果年份相同
        mIndex = (_endDate?.month ?? 0) - (minDate.month ?? 0);
      } else {
        mIndex = (_endDate?.month ?? 0) - 1;
      }
      scrollCtrl[DateType.Month]?.jumpToItem(mIndex);
      _setPicker(DateType.Month, mIndex);
      List<String> list = (widget.route.endText ?? "").split('-');
      _endDate = PDuration(year: int.parse(list[0]), month: int.parse(list[1]), day: int.parse(list[2]));
      //更新_selectData用于数据回调
      _selectData = _endDate ?? PDuration();
      int dIndex = 0;
      if (minDate.year == _endDate?.year && minDate.month == _endDate?.month) {
        //如果年份相同,并且月份相同
        dIndex = (_endDate?.day ?? 0) - (minDate.day ?? 0);
      } else {
        dIndex = (_endDate?.day ?? 0) - 1;
      }
      scrollCtrl[DateType.Day]?.jumpToItem(dIndex);
      _setPicker(DateType.Day, dIndex);
    });
  }

  ///初始化快筛样式开始时间
  void initSelectorStartDate(int index) {
    print("initSelectorStartDate,index==$index");
    if (widget.route.calculateStartTimeWhenClick != null) {
      _startDate = widget.route.calculateStartTimeWhenClick!.call(index, _endDate ?? PDuration());
      if (_startDate != null) {
        _selectStartData = _startDate!;
        _startText = '${_startDate!.year}-'
            '${TimeUtils.intToStr(_startDate!.month ?? 0)}-'
            '${TimeUtils.intToStr(_startDate!.day ?? 0)}';
        _caculatedStartText = _startText;
      }
      if (_startTextSelected) {
        handleClickStartTime();
      }
    }
  }
}

class _BottomPickerLayout extends SingleChildLayoutDelegate {
  _BottomPickerLayout(this.progress, this.pickerStyle);

  final double progress;
  final PickerStyle pickerStyle;

  @override
  BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
    return BoxConstraints(
      minWidth: constraints.maxWidth,
      maxWidth: constraints.maxWidth,
      minHeight: 0.0,
    );
  }

  @override
  Offset getPositionForChild(Size size, Size childSize) {
    double height = size.height - childSize.height * progress;
    return Offset(0.0, height);
  }

  @override
  bool shouldRelayout(_BottomPickerLayout oldDelegate) {
    return progress != oldDelegate.progress;
  }
}
